package com.feinno.urcs.group.http.task;

import com.feinno.sip.message.SipResponse;
import com.feinno.sip.transaction.TransactionClient;
import com.feinno.sip.transaction.TransactionClientListener;
import com.feinno.urcs.group.GroupConstants;
import com.feinno.urcs.group.pd.upstream.entity.PublicGroup_List_Entry;
import com.feinno.urcs.group.pd.upstream.entity.PublicGroup_List_Entry_DisplayName;
import com.feinno.urcs.group.http.config.GroupHttpConstant;
import com.feinno.urcs.group.pd.downstream.entity.XcapDiff;
import com.feinno.urcs.group.pd.downstream.entity.XcapDiff_Document;
import com.feinno.urcs.group.pd.downstream.entity.XcapDiff_Document_Add;
import com.feinno.urcs.group.pd.task.entity.PdGroupInviteReplyNotifyArgs;
import com.feinno.urcs.sipservlet.SipServletFuture;
import com.feinno.urcs.sipservlet.SipServletRequest;
import org.helium.framework.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.stream.XMLStreamException;

/**
 * Created by wuzhiguo on 15-6-5.
 */
public class PdGroupInviteReplyNotifyTask extends PdBaseNotifyTask implements Task<PdGroupInviteReplyNotifyArgs> {

    private static final Logger LOGGER = LoggerFactory.getLogger(PdGroupInviteReplyNotifyTask.class);

    @Override
    public void processTask(PdGroupInviteReplyNotifyArgs args) {
        try {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Received Args: %s", args));
            }

            byte[] content = createContentXml(args);
            SipServletRequest request = createSipRequest(args.getBaseGroupNotify(), content);
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info(String.format("Create SipRequest: %s", request.toString()));
            }

            SipServletFuture future = request.sendRequest();
            future.setListener(new TransactionClientListener() {
                @Override
                public void onTransProvisionalResponse(TransactionClient tc, SipResponse response) {
                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info(String.format("Received SipResponse: %s", response.toString()));
                    }
                }

                @Override
                public void onTransSuccessResponse(TransactionClient tc, SipResponse response) {
                    if (LOGGER.isInfoEnabled()) {
                        LOGGER.info(String.format("Received SipResponse: %s", response.toString()));
                    }
                }

                @Override
                public void onTransFailureResponse(TransactionClient tc, SipResponse response) {
                    LOGGER.error(String.format("Trans Failure.\n " +
                                    "SipRequest: %s\n " +
                                    "SipResponse: %s",
                            request.toString(),
                            response.toString()));
                }

                @Override
                public void onTransTimeout(TransactionClient tc) {
                    LOGGER.error(String.format("Trans Timeout. SipRequest: %s", request.toString()));
                }
            });

        } catch (Exception ex) {
            LOGGER.error(String.format("process() Error. Received Args: %s", args), ex);
        }
    }

    private byte[] createContentXml(PdGroupInviteReplyNotifyArgs args) throws XMLStreamException {
        XcapDiff xcapDiff = new XcapDiff();
        XcapDiff_Document document = new XcapDiff_Document();
        xcapDiff.setDocument(document);
        document.setPreviousEtag(args.getBaseGroupNotify().getPreviousEtag());
        document.setNewEtag(args.getBaseGroupNotify().getNewEtag());
        document.setSel(String.format(GroupConstants.PUBLIC_GROUP_IDENTIFIER_TEMPLATE, args.getBaseGroupNotify().getGroupUri()));

        XcapDiff_Document_Add add = new XcapDiff_Document_Add();
        document.setAdd(add);

        add.setSel("public-group/list");
        PublicGroup_List_Entry entry = new PublicGroup_List_Entry();
        add.setEntry(entry);

        entry.setUri(args.getGroupMemberUri());
        entry.setStatus("active");
        PublicGroup_List_Entry_DisplayName displayName = new PublicGroup_List_Entry_DisplayName();
        displayName.setInnerText(args.getDisplayName());
        entry.setDisplayName(displayName);

        return xcapDiff.toXmlByteArray();
    }
}